import os,sys
import alive_progress
if not os.path.exists("out"):
    os.makedirs("out")
if len(sys.argv)==2:
    os.chdir("./test/"+sys.argv[1]+"/")
    code = ("make", "python build.py", "/bin/sh ./build.sh", "powershell build.ps1", "cmd.exe /c build.bat")
    file = ("makefile", "build.py", "build.sh", "build.ps1", "build.bat")
    for i in range(len(file)):
        if os.path.exists(file[i]):
            exit(os.system(code[i]))
    exit(1)
filelength = 0
finallen = 1474560
def compile(cmd,file,aft):
    i = os.path.split(file)[-1]
    cmd = cmd.format(src='"'+file+'"',dst='"'+os.path.join("out",".".join(i.split(".")[:-1])+'.'+aft)+'"')
    print(("编译"+file+"...").ljust(30),cmd)
    stat = os.system(cmd)
    if stat:
        print("E: 编译"+file+"时出现错误。（子进程返回"+str(stat)+"）")
        exit(1)
    return os.path.join("out",".".join(i.split(".")[:-1])+'.'+aft)
files = []
def compileall():
    for path,dir,file in os.walk("."):
        if(path == "." or 
        path == os.path.join(".","out") or 
        path == os.path.join(".",".git") or
        path.startswith(os.path.join(".", ".venv"))or
           path.startswith(os.path.join(".", "test"))):
            continue
        for i in file:
            match(i.split(".")[-1]):
                case 'c':
                    outfile = compile("gcc -m32 -O2 -std=c99 -ffreestanding -fno-builtin -nostdlib -c {src} -o {dst}",os.path.join(path,i),'o')
                    outfile = compile("ld -m elf_i386 {src} -o {dst} -Ttext=0x30400",outfile,'bin')
                    
                case 'cpp' | 'cxx' | 'cp' | 'cx': 
                    outfile = compile("g++ -m32 -O2 -std=c++14 -ffreestanding -fno-builtin -nostdlib -c {src} -o {dst}",os.path.join(path,i),'o')
                    outfile = compile("ld -m elf_i386 {src} -o {dst} -Ttext=0x30400",outfile,'bin')
                case 'asm':
                    outfile = compile("nasm {src} -o {dst}",os.path.join(path,i),'bin')
                    
                case _:
                    continue
outfiles = \
"""
boot.bin
loader.bin
kernel.bin
""".splitlines()[1:]
def filluntil(final, progress, size):
    global filelength
    while filelength < size:
        final.write(b'\x00')
        filelength += 1
        progress()
def write(final, progress, src):
    global filelength
    with open(os.path.join("out",src),"rb") as nf:
        while nf.readable():
            chunk = nf.read(1024)
            size = len(chunk)
            if(size == 0): break
            progress(size)
            filelength += size
            final.write(chunk)
def mkfloppy():
    global filelength
    open("OS.tmp.img","w").close()
    with alive_progress.alive_bar(total=finallen,title="写入OS.img",unit="B",scale="SI2") as progress:
        with open("OS.tmp.img",'r+b') as final:
            write(final, progress, "boot.bin")
            write(final, progress, "loader.bin")
            write(final, progress, "kernel.bin")
            filluntil(final, progress, finallen)

file = "OS.tmp.img"
def copytemp():
    import time


    st = time.time()

    while True:
        try:
            os.rename("OS.tmp.img", "OS.img")
        except:
            s = f"等待虚拟机关闭...{time.time()-st:.0f}s"
            print(s, end="\b"*(len(s)+7), flush=True)
            continue
        break
compileall()
mkfloppy()
copytemp()